/**
 * Copyright (C) 2009 Fsti Inc.
 *
 */
package com.fsti.ppmw.port.payment;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

/**
 * 支付平台Web服务-APServices客户端	
 * 
 * 
 * @author Song Qing
 *
 */
public class APServicesClient implements Client {
	/**
	 * 后台线程池 
	 */
	private static ExecutorService paymentService = Executors.newFixedThreadPool(8);

	/**
	 * 请求参数
	 */
	private RequestParams requestParams;

	/**
	 * 配置参数
	 */
	private ConfigParams configParams;
	/**
	 * 交易流水号
	 */
	private String apTransId;
	/**
	 * 能力类型
	 */
	private AbilityType abilityType;
	/**
	 * 移动号码前缀
	 */
	private static final List<String> MOBILE_NO_PREFIX = Arrays.asList(new String[] { "13", "15", "18" });

	/**
	 * 调用
	 * @param RequestParams
	 * @param PaymentDAO
	 * @return	ReturnValue
	 * @throws InterruptedException 
	 */
	public String call(RequestParams requestParams, PaymentDAO paymentDAO) throws InterruptedException {

		// 验证参数
		//Validation.Validate(configParams, requestParams);
		this.requestParams = requestParams;

		//判断当前能力类型
		String abilityTypesName = configParams.getAbilityTypes().get(requestParams.getAbilityType());
		if (StringUtils.isBlank(abilityTypesName)) {
			throw new IllegalArgumentException("当前能力类型名称不能为空！");
		}
		abilityType = AbilityType.valueOf(abilityTypesName);

		//生成附加信息XML串
		String expattach = toXml();

		//生成交易流水号
		apTransId = TransactionNumber.generate(configParams.getApId(), requestParams.getTimeStamp());

		//后台线程调用支付平台服务

		PaymentServiceThread paymentThread = new PaymentServiceThread(requestParams, configParams, paymentDAO,
				apTransId, abilityType, expattach);
		paymentService.execute(paymentThread);

		//返回值
		return Client.returnValue;
	}

	public void setConfigParams(ConfigParams configParams) {
		this.configParams = configParams;
	}

	/**
	 * 生成XML数据
	 * 
	 * @return 依据附加信息类型，生成相应的XML数据
	 */
	private String toXml() {
		Document document = DocumentHelper.createDocument();
		Element root = document.addElement("DATA");
		Element base = root.addElement("BASE");
		switch (abilityType) {
		case QUERY_ORDER:
			base.addElement("user_tel").addText(requestParams.getUserTel());
			break;
		case PAYMENT_ORDER:
			base.addElement("op_code").addText(getOpCode());
			base.addElement("account_type").addText(getAccountType());
			base.addElement("account_no").addText(requestParams.getUserTel());
			base.addElement("account_pwd").addText(requestParams.getPassword());
			Element exp = root.addElement("EXP");
			exp.addElement("area_code").addText(requestParams.getAreaCode());
			break;
		case QUERY_POINTS:
			base.addElement("op_code").addText(getOpCode());
			base.addElement("account_type").addText(getAccountType());
			base.addElement("account_no").addText(requestParams.getUserTel());
			base.addElement("account_pwd").addText(requestParams.getPassword());
			break;
		}
		;
		return document.asXML();
	}

	/**
	 * 获取操作码
	 * 
	 * @return 操作码
	 */
	private String getOpCode() {
		Map<String, String> opCodes = configParams.getOpCodes();
		return opCodes.get(abilityType.name());
	}

	/**
	 * 获取支付帐户类型
	 * 
	 * @return 支付帐户类型
	 */
	private String getAccountType() {
		AccountTypes accountType = AccountTypes.FIXED_NO;
		if (isMobileNo()) {
			accountType = AccountTypes.MOBILE_NO;
		}
		Map<String, String> accountTypes = configParams.getAccountTypes();
		return accountTypes.get(accountType.name());
	}

	/**
	 * 是否为移动号码
	 * @return 若为移动号码，则返回true
	 */
	private boolean isMobileNo() {
		boolean isMobileNo = false;
		String userTel = requestParams.getUserTel();
		for (String prefix : MOBILE_NO_PREFIX) {
			isMobileNo = isMobileNo || StringUtils.startsWith(userTel, prefix);
		}
		return isMobileNo;
	}
}
